package com.own.component.util.excel.method;

import com.own.component.util.excel.exception.ExcelException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * WorkbookMethod
 *
 * @author chenxueli
 * @date 2022-10-09 14:57:00
 */
public class WorkbookMethod {

    /**
     * 从文件中读取excel信息
     *
     * @param file 文件信息
     * @return excel信息
     */
    public static Workbook get(MultipartFile file) {
        try {
            return get(file.getInputStream());
        } catch (IOException e) {
            throw new ExcelException("读取excel文件异常,可将转换转换格式后重试");
        }
    }

    /**
     * 从文件中读取excel信息
     *
     * @param file 文件信息
     * @return excel信息
     */
    public static Workbook get(File file) {
        try {
            return get(new FileInputStream(file));
        } catch (IOException e) {
            throw new ExcelException("读取excel文件异常,可将转换转换格式后重试");
        }
    }

    /**
     * 从文件流中读取excel信息
     *
     * @param inputStream 输入流
     * @return excel信息
     */
    public static Workbook get(InputStream inputStream) {
        var inputArray = copyInputStream(inputStream);
        try {
            var fileMagic = FileMagic.valueOf(inputArray[0]);
            return switch (fileMagic) {
                case OLE2 -> new HSSFWorkbook(inputArray[1]);
                case OOXML -> new XSSFWorkbook(inputArray[1]);
                default -> throw new ExcelException("读取excel文件异常,可将转换转换格式后重试");
            };
        } catch (IOException e) {
            throw new ExcelException("读取excel文件异常,可将转换转换格式后重试");
        } finally {
            try {
                inputStream.close();
                inputArray[0].close();
                inputArray[1].close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 克隆文件信息
     *
     * @param inputStream 文件流
     * @return 复制的对象
     */
    public static InputStream[] copyInputStream(InputStream inputStream) {
        var byteArrayOutputStream = new ByteArrayOutputStream();
        var buffer = new byte[1024];
        try {
            int len;
            while ((len = inputStream.read(buffer)) > -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
            byteArrayOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new InputStream[]{
                new ByteArrayInputStream(byteArrayOutputStream.toByteArray()),
                new ByteArrayInputStream(byteArrayOutputStream.toByteArray())
        };
    }

}
